home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1993 / Internet Info CD-ROM (Walnut Creek) (1993).iso / networking / ip / ka9q / aztecnos.arc / AX25CMD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-18  |  9.8 KB  |  483 lines

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "mbuf.h"
  4. #include "timer.h"
  5. #include "proc.h"
  6. #include "iface.h"
  7. #include "ax25.h"
  8. #include "lapb.h"
  9. #include "cmdparse.h"
  10. #include "socket.h"
  11. #include "ax25tnc.h"
  12. #include "session.h"
  13.  
  14.  
  15. extern char Notval[];
  16. extern int Digipeat;
  17. extern int16 T3init,N2,Maxframe,Paclen,Pthresh,Axwindow,Axirtt,Axversion;
  18. extern int errno;
  19.  
  20. void ax_in();
  21. static int domycall(),dodigipeat(),doaxirtt(),doaxstat(),dot3(),domaxframe(),
  22.     doaxwindow(),dopaclen(),don2(),doaxreset(),dopthresh(),doaxroute(),
  23.     doversion();
  24.  
  25. char *Ax25states[] = {
  26.     "Disconnected",
  27.     "Conn pending",
  28.     "Disc pending",
  29.     "Connected",
  30.     "Recovery",
  31.     "Frame Reject",
  32. };
  33.  
  34. /* Ascii explanations for the disconnect reasons listed in lapb.h under
  35.  * "reason" in ax25_cb
  36.  */
  37. char *Axreasons[] = {
  38.     "Normal",
  39.     "DM received",
  40.     "Timeout"
  41. };
  42.  
  43. static struct cmds axcmds[] = {
  44.     "digipeat",    dodigipeat,    0, 0, NULLCHAR,
  45.     "irtt",        doaxirtt,    0, 0, NULLCHAR,
  46.     "maxframe",    domaxframe,    0, 0, NULLCHAR,
  47.     "mycall",    domycall,    0, 0, NULLCHAR,
  48.     "paclen",    dopaclen,    0, 0, NULLCHAR,
  49.     "pthresh",    dopthresh,    0, 0, NULLCHAR,
  50.     "reset",    doaxreset,    0, 2, "ax25 reset <axcb>",
  51.     "retry",    don2,        0, 0, NULLCHAR,
  52.     "route",    doaxroute,    0, 0, NULLCHAR,
  53.     "status",    doaxstat,    0, 0, NULLCHAR,
  54.     "t3",        dot3,        0, 0, NULLCHAR,
  55.     "version",    doversion,    0, 0, NULLCHAR,
  56.     "window",    doaxwindow,    0, 0, NULLCHAR,
  57.     NULLCHAR,    NULLFP,        0, 0, "ax25 subcommands: digipeat maxframe mycall paclen pthresh reset retry status\n\tt1 t3 window",
  58. };
  59. /* Multiplexer for top-level ax25 command */
  60. doax25(argc,argv)
  61. int argc;
  62. char *argv[];
  63. {
  64.     return subcmd(axcmds,argc,argv);
  65. }
  66.  
  67. static
  68. doaxreset(argc,argv)
  69. int argc;
  70. char *argv[];
  71. {
  72.     struct ax25_cb *axp;
  73.  
  74.     axp = (struct ax25_cb *)ltop(htol(argv[1]));
  75.     if(!ax25val(axp)){
  76.         printf(Notval);
  77.         return 1;
  78.     }
  79.     reset_ax25(axp);
  80.     return 0;
  81. }
  82.  
  83. /* Display AX.25 link level control blocks */
  84. static
  85. doaxstat(argc,argv)
  86. int argc;
  87. char *argv[];
  88. {
  89.     register int i;
  90.     register struct ax25_cb *axp;
  91.     char tmp[10];
  92.  
  93.     if(argc < 2){
  94.         printf("    &AXB Snd-Q   Rcv-Q   Remote    State\n");
  95.         for(i=0;i<NHASH;i++){
  96.             for(axp = Ax25_cb[i];axp != NULLAX25; axp = axp->next){
  97.                 pax25(tmp,&axp->remote);
  98.                 printf("%8lx %-8d%-8d%-10s%s\n",
  99.                     (long)axp,
  100.                     len_q(axp->txq),len_mbuf(axp->rxq),
  101.                     tmp,Ax25states[axp->state]);
  102.             }
  103.         }
  104.         return 0;
  105.     }
  106.     axp = (struct ax25_cb *)ltop(htol(argv[1]));
  107.     if(!ax25val(axp)){
  108.         printf(Notval);
  109.         return 1;
  110.     }
  111.     st_ax25(axp);
  112.     return 0;
  113. }
  114. /* Dump one control block */
  115. void
  116. st_ax25(axp)
  117. register struct ax25_cb *axp;
  118. {
  119.     char tmp[10];
  120.  
  121.     if(axp == NULLAX25)
  122.         return;
  123.     printf("&AXB Remote   RB V(S) V(R) Unack P Retry State\n");
  124.     pax25(tmp,&axp->remote);
  125.     printf("%4x %-9s",(int)axp,tmp);
  126.     putchar(axp->flags.rejsent ? 'R' : ' ');
  127.     putchar(axp->flags.remotebusy ? 'B' : ' ');
  128.     printf(" %4d %4d",axp->vs,axp->vr);
  129.     printf(" %02u/%02u %u",axp->unack,axp->maxframe,axp->proto);
  130.     printf(" %02u/%02u",axp->retries,axp->n2);
  131.     printf(" %s\n",Ax25states[axp->state]);
  132.  
  133.     printf("SRT = %lu ",axp->srt * MSPTICK);
  134.     printf("T1: ");
  135.     if(run_timer(&axp->t1))
  136.         printf("%lu",read_timer(&axp->t1) * MSPTICK);
  137.     else
  138.         printf("stop");
  139.     printf("/%lu ms; ",dur_timer(&axp->t1) * MSPTICK);
  140.  
  141.     printf("T3: ");
  142.     if(run_timer(&axp->t3))
  143.         printf("%lu",read_timer(&axp->t3) * MSPTICK);
  144.     else
  145.         printf("stop");
  146.     printf("/%lu ms\n",dur_timer(&axp->t3) * MSPTICK);
  147.  
  148. }
  149.  
  150. /* Display or change our AX.25 address */
  151. static
  152. domycall(argc,argv)
  153. int argc;
  154. char *argv[];
  155. {
  156.     char buf[15];
  157.  
  158.     if(argc < 2){
  159.         pax25(buf,&Mycall);
  160.         printf("%s\n",buf);
  161.         return 0;
  162.     }
  163.     if(setcall(&Mycall,argv[1]) == -1)
  164.         return -1;
  165.     Mycall.ssid |= E;
  166.     return 0;
  167. }
  168.  
  169. /* Control AX.25 digipeating */
  170. static
  171. dodigipeat(argc,argv)
  172. int argc;
  173. char *argv[];
  174. {
  175.     if(argc == 1) {
  176.         printf("digipeat %s\n",Digipeat ? "on" : "off");
  177.     } else {
  178.         if(strcmp(argv[1],"on") == 0)
  179.             Digipeat = 1;
  180.         else
  181.             Digipeat = 0;
  182.     }
  183. }
  184. static
  185. doversion(argc,argv)
  186. int argc;
  187. char *argv[];
  188. {
  189.     if(argc == 1){
  190.         printf("AX25 version %s\n",Axversion == V1 ? "V1" : "V2");
  191.         return 0;
  192.     }
  193.     if(strchr(argv[1],'1') != NULLCHAR)
  194.         Axversion = V1;
  195.     else if(strchr(argv[1],'2') != NULLCHAR)
  196.         Axversion = V2;
  197.     else
  198.         return -1;
  199. }
  200.  
  201. static
  202. doaxirtt(argc,argv)
  203. int argc;
  204. char *argv[];
  205. {
  206.     if(argc == 1){
  207.         printf("AX25 initial round trip time: %lu ms\n",Axirtt*MSPTICK);
  208.     } else {
  209.         Axirtt = atol(argv[1]) / MSPTICK;
  210.     }
  211. }
  212.  
  213. /* Set idle timer */
  214. static
  215. dot3(argc,argv)
  216. int argc;
  217. char *argv[];
  218. {
  219.     if(argc == 1) {
  220.         printf("T3 %lu ms\n",(long)T3init * MSPTICK);
  221.     } else {
  222.         T3init = atol(argv[1]) / MSPTICK;
  223.     }
  224. }
  225.  
  226. /* Set retry limit count */
  227. static
  228. don2(argc,argv)
  229. int argc;
  230. char *argv[];
  231. {
  232.     if(argc == 1) {
  233.         printf("Retry %u\n",N2);
  234.     } else {
  235.         N2 = atoi(argv[1]);
  236.     }
  237. }
  238.  
  239. /* Set maximum number of frames that will be allowed in flight */
  240. static
  241. domaxframe(argc,argv)
  242. int argc;
  243. char *argv[];
  244. {
  245.     if(argc == 1) {
  246.         printf("Maxframe %u\n",Maxframe);
  247.     } else {
  248.         Maxframe = atoi(argv[1]);
  249.     }
  250. }
  251.  
  252. /* Set maximum length of I-frame data field */
  253. static
  254. dopaclen(argc,argv)
  255. int argc;
  256. char *argv[];
  257. {
  258.     if(argc == 1) {
  259.         printf("Paclen %u\n",Paclen);
  260.     } else {
  261.         Paclen = atoi(argv[1]);
  262.     }
  263. }
  264. /* Set size of I-frame above which polls will be sent after a timeout */
  265. static
  266. dopthresh(argc,argv)
  267. int argc;
  268. char *argv[];
  269. {
  270.     if(argc == 1) {
  271.         printf("Pthresh %u\n",Pthresh);
  272.     } else {
  273.         Pthresh = atoi(argv[1]);
  274.     }
  275. }
  276.  
  277. /* Set high water mark on receive queue that triggers RNR */
  278. static
  279. doaxwindow(argc,argv)
  280. int argc;
  281. char *argv[];
  282. {
  283.     if(argc == 1) {
  284.         printf("Axwindow %u\n",Axwindow);
  285.     } else {
  286.         Axwindow = atoi(argv[1]);
  287.     }
  288. }
  289. /* End of ax25 subcommands */
  290.  
  291. /* Initiate interactive AX.25 connect to remote station */
  292. doconnect(argc,argv)
  293. int argc;
  294. char *argv[];
  295.  {
  296.     struct session *sp;
  297.     int s;
  298.     struct sockaddr_ax fsocket;
  299.     struct mbuf *bp;
  300.     char *cp;
  301.  
  302.     /* Allocate a session descriptor */
  303.     if((sp = newsession(argv[2],AX25TNC)) == NULLSESSION){
  304.         printf("Too many sessions\n");
  305.         return 1;
  306.     }
  307.     Current = sp;
  308.     sp->cb.ax25 = (struct ax25tnc *)calloc(1,sizeof(struct ax25tnc));
  309.     sp->cb.ax25->session = sp;
  310.     sp->cb.ax25->output = Curproc;
  311.  
  312.     s = sp->s = socket(AF_AX25,SOCK_STREAM,0);
  313.     
  314.     fsocket.sax_family = AF_AX25;
  315.     setcall(&fsocket.ax25_addr,argv[2]);
  316.     strncpy(fsocket.iface,argv[1],ILEN);
  317.     printf("Trying %s...\n",psocket((struct sockaddr *)&fsocket));
  318.     if(connect(s,(char *)&fsocket,SOCKSIZE) == -1){
  319.         printf("AX25 session %u failed: %s\n",
  320.          (unsigned)(sp-Sessions),sockerr(s));
  321.         close_s(s);
  322.         free((char *)sp->cb.ax25);
  323.         freesession(sp);
  324.         return 1;
  325.     }
  326.     printf("AX25 session %u connected to %s\n",
  327.         (unsigned)(sp-Sessions),sp->name);
  328.     sp->cb.ax25->output = Curproc;
  329.     sp->cb.ax25->input = newproc("ax_in",1024,ax_in,0,sp->cb.ax25);
  330.     for(;;){
  331.         while(sp->input == NULLBUF)
  332.             pwait(&sp->input);
  333.  
  334.         bp = dequeue(&sp->input);
  335.  
  336.         /* If we're recording, record it */
  337.         if(sp->record != NULLFILE)
  338.             write_p(sp->record,bp);
  339.  
  340.         /* Get rid of the trailing newline */
  341.         if((cp = strchr(bp->data,'\n')) != NULLCHAR){
  342.             *cp = '\0';
  343.             bp->cnt--;
  344.         }
  345.         if(send_mbuf(s,bp,0,NULLCHAR,0) == -1)
  346.             break;
  347.     }
  348.     killproc(sp->cb.ax25->input);
  349.     close_s(s);
  350.     free((char *)sp->cb.ax25);
  351.     freesession(sp);
  352.     return 0;
  353. }
  354. /* Display and modify AX.25 routing table */
  355. static int
  356. doaxroute(argc,argv)
  357. int argc;
  358. char *argv[];
  359. {
  360.     char buf[30];
  361.     int i,j,ndigis;
  362.     register struct ax_route *axr;
  363.     struct ax25_addr target,digis[MAXDIGIS];
  364.  
  365.     if(argc < 2){
  366.         printf("Target    Type   Digipeaters\n");
  367.         for(i=0;i<NAXROUTE;i++){
  368.             for(axr = Ax_routes[i];axr != NULLAXR;axr = axr->next){
  369.                 pax25(buf,&axr->target);
  370.                 printf("%-10s%-6s",buf,
  371.                  axr->type == AX_LOCAL ? "Local":"Auto");
  372.                 for(j=0;j<axr->ndigis;j++){
  373.                     pax25(buf,&axr->digis[j]);
  374.                     printf(" %s",buf);
  375.                 }
  376.                 printf("\n");
  377.             }
  378.         }
  379.         return;
  380.     }
  381.     if(argc < 3){
  382.         printf("Usage: ax25 route add <target> [digis...]\n");
  383.         printf("       ax25 route drop <target>\n");
  384.         return;
  385.     }
  386.     setcall(&target,argv[2]);
  387.     switch(argv[1][0]){
  388.     case 'a':    /* Add route */
  389.         if(argc < 3){
  390.             printf("Usage: ax25 route add <target> [digis...]\n");
  391.             return;
  392.         }
  393.         ndigis = argc - 3;
  394.         for(i=0;i<ndigis;i++)
  395.             setcall(&digis[i],argv[i+3]);
  396.  
  397.         ax_add(&target,AX_LOCAL,&digis[0],ndigis);
  398.         break;
  399.     case 'd':    /* Drop route */
  400.         ax_drop(&target);
  401.         break;
  402.     default:
  403.         printf("Unknown command %s\n",argv[1]);
  404.         break;
  405.     }
  406. }
  407. void
  408. ax_upload(unused,sp)
  409. int unused;
  410. struct session *sp;
  411. {
  412.     struct mbuf *bp;
  413.     char *cp;
  414.     int c;
  415.  
  416.     for(;;){
  417.         bp = alloc_mbuf(BUFSIZ);
  418.         cp = bp->data;
  419.         while(bp->cnt < BUFSIZ){
  420.             if((c = getc(sp->upload)) == EOF)
  421.                 break;
  422.             if(c == '\r')
  423.                 continue;
  424.             if(c == '\n')
  425.                 c = '\r';
  426.             *cp++ = c;
  427.             bp->cnt++;
  428.         }
  429.         if(bp->cnt == 0){
  430.             free_p(bp);
  431.             break;
  432.         } else if(send_mbuf(sp->s,bp,0,NULLCHAR,0) == -1)
  433.             break;
  434.     }
  435.     fclose(sp->upload);
  436.     sp->cb.ax25->upload = NULLPROC;
  437. }
  438. /* AX.25 TNC receive process */
  439. void
  440. ax_in(unused,tnc)
  441. int unused;
  442. struct ax25tnc *tnc;
  443. {
  444.     char c;
  445.     struct session *sp;
  446.     char *cp;
  447.     struct mbuf *bp;
  448.     int s;
  449.  
  450.     sp = tnc->session;
  451.     s = sp->s;
  452.  
  453.     for(;;){
  454.         if(recv_mbuf(s,&bp,0,0,NULLCHAR,0) == -1)
  455.             break;
  456.         while(pullup(&bp,&c,1) == 1){
  457.             /* Suspend output if we're not current */
  458.             while(Current != sp)
  459.                 pwait(sp);
  460.  
  461.             putchar(c);
  462.             if(c == '\r')
  463.                 putchar('\n');
  464.  
  465.             if(sp->record != NULLFILE){
  466.                 putc(c,sp->record);
  467.                 if(c == '\r')
  468.                     putc('\r',sp->record);
  469.             }
  470.         }
  471.     }
  472.     /* Close seen from remote host */
  473.     cp = sockerr(s);
  474.     printf("AX25 session %u closed: %s\n", (unsigned)(sp - Sessions),
  475.      cp != NULLCHAR ? cp : "EOF");
  476.     close_s(s);
  477.     tnc->input = NULLPROC;
  478.     killproc(tnc->output);
  479.     free((char *)tnc);
  480.     freesession(sp);
  481. }
  482.  
  483.